#ifndef __BASE_ACCOUNT_MGR_H__
#define __BASE_ACCOUNT_MGR_H__

#include <map>
#include <mutex>
#include <string>
#include <vector>

#include <common/base/manager.h>

class Session;

struct AccountInfo
{
    uint16_t areaID;
    uint32_t accID;
    uint64_t regTime;
    // uint64_t curLoginID;

    std::string accName;
    std::string source;

    std::shared_ptr<Session> curLoginSession; // 当前连接的会话

    AccountInfo() : areaID(0), accID(0), regTime(0) {}
};

struct PlayerCreateInfo
{
    uint32_t playerID;
    std::string playerName;
    uint16_t headID;
    uint64_t lastLoginTime;

    // std::shared_ptr<Session> gsSession;

    PlayerCreateInfo() : playerID(0), headID(0), lastLoginTime(0) {}
};

class AccountMgr : public IManager
{
public:
    AccountMgr() : gsIndex_(0) {}

    ~AccountMgr() {}

    virtual bool init();

    /**
     * @desc 查询帐号ID
     * @param accountName 帐号名
     * @param source 帐号来源
     * @retrun 帐号ID
     * @auth Qiwei.Gu
     * @date 2015-04-29 11:37:23
     */
    std::shared_ptr<AccountInfo> getAccInfo(const std::string& accountName, const std::string& source)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        auto it = accounts_.find(std::make_pair(accountName, source));
        return it == accounts_.end() ? 0 : it->second;
    }

    std::shared_ptr<AccountInfo> getAccInfo(uint32_t accID)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        auto it = accInfos_.find(accID);
        return it == accInfos_.end() ? std::shared_ptr<AccountInfo>() : it->second;
    }

    /**
     * @desc 向数据库添加帐号
     * @param accountName 帐号名
     * @param source 帐号来源
     * @param accID 数据库自动生成的帐号ID
     * @return 添加成功返回true
     * @auth Qiwei.Gu
     * @date 2015-04-29 11:38:27
     */
    bool createAccount(const std::string& accountName, const std::string& source, uint32_t& accID);

    /**
     * @desc 生成新的随机名
     * @auth Qiwei.Gu
     * @date 2015-04-29 11:43:54
     */
    std::string genRandName();

    /**
     * @desc 获得玩家列表
     * @auth Qiwei.Gu
     * @date 2015-04-29 12:22:58
     */
    void getPlayerList(uint32_t accID, std::vector<PlayerCreateInfo>& players);

    /**
     * @desc 玩家名是否存在
     * @param playerName 玩家名
     * @auth Qiwei.Gu
     * @date 2015-04-29 14:47:53
     */
    bool getPlayerID(const std::string& playerName)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        auto it = players_.find(playerName);
        return it == players_.end() ? 0 : it->second;
    }

    /**
     * @desc 从数据库中创建角色
     * @param playerName 玩家名
     * @param accID 帐号ID
     * @param headID 角色头像ID
     * @auth Qiwei.Gu
     * @date 2015-04-29 14:57:44
     */
    bool createPlayer(const std::string& playerName, uint32_t accID, uint16_t headID, uint32_t& playerID);

    /**
     * @desc 选择一个GS连接
     * @param cltSession 客户端连接
     * @param playerID 玩家ID
     * @auth Qiwei.Gu
     * @date 2015-04-30 20:04:33
     */
    std::shared_ptr<Session> chooseGsSession(const std::shared_ptr<Session>& cltSession, uint32_t playerID);


private:
    /**
     * @desc 初始化，从数据库中加载所有账户信息
     * @auth Qiwei.Gu
     * @date 2015-04-29 11:35:14
     */
    bool initAccount();

    /**
     * @desc 从数据库中加载所有角色信息
     * @auth Qiwei.Gu
     * @date 2015-04-29 14:31:34
     */
    bool initPlayer();

    /**
     * @desc 初始化随机名配置
     * @auth Qiwei.Gu
     * @date 2015-04-29 11:45:05
     */
    bool initRandName();

private:
    std::mutex mutex_;
    std::map<std::pair<std::string, std::string>, std::shared_ptr<AccountInfo>> accounts_;
    std::map<uint32_t, std::shared_ptr<AccountInfo>> accInfos_;

    std::map<std::string, uint32_t> players_;
    uint16_t gsIndex_;

    // rand names
    std::vector<std::string> preNames_;
    std::vector<std::string> sufNames_;
};

#endif //  __BASE_ACCOUNT_MGR_H__
